package com.nhc.database.manager;

import android.content.Context;
import android.os.Environment;
import android.util.Xml;

import com.astrob.activitys.AppContext;
import com.astrob.model.LonLat;
import com.astrob.naviframe.Start;
import com.astrob.util.SysUtils;
import com.astrob.util.Utils;
import com.nhc.database.dbmodel.Route;
import com.nhc.database.dbmodel.TrackPoint;
import com.nhc.database.dbmodel.WayPoint;
import com.nhc.database.dbmodel.WayTrail;
import com.nhc.database.greendao.RouteDao;
import com.nhc.database.greendao.TrackPointDao;
import com.nhc.database.greendao.WayPointDao;
import com.nhc.database.greendao.WayTrailDao;
import com.nhc.model.Coordinate;
import com.nhc.model.KMLFolder;
import com.nhc.model.KMLPlacemark;

import org.xmlpull.v1.XmlPullParser;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import zuo.biao.library.util.StringUtil;


//导入导出
public class IECenter {

    private static IECenter instance = new IECenter();

    public static IECenter getInstance() {
        return instance;
    }

    Context mContext;

    public void init(Context context) {
        mContext = context;
        checkDir();
    }

    public void checkDir() {
        //导出目录修正（如果不是华测的设备，）
        if (SysUtils.getInstance().is240x320) {
            EXDIR = Environment.getExternalStorageDirectory() + "/";
            EXDIR_GPX = EXDIR + "GPX/";
            EXDIR_KML = EXDIR + "KML/";
        } else {
            File file = new File(EXDIR);
            if (!file.exists()) {
                EXDIR = Start.RUNDIR;
                EXDIR_GPX = EXDIR + "HCMap_EX/gpx/";
                EXDIR_KML = EXDIR + "HCMap_EX/KML/";
            }
        }
    }

    //导出目录（只能是内部存储，不能SD卡）
    public static String EXDIR = Start.RUNDIR;
    public static String EXDIR_GPX = EXDIR + "HCMap_EX/gpx/";
    public static String EXDIR_KML = EXDIR + "HCMap_EX/KML/";

    //导入目录--在DaoruActivity里定义
//    public static String EXDIR2 = "/mnt/sdcard2/HCMap_EX/";


    // 传入坐标尚未转换为WGS84
    public void export2GPX(String fileName, ArrayList<WayPoint> waypointList, ArrayList<Route> routeList, ArrayList<WayTrail> waytrailList) {
        if (waypointList == null && routeList == null && waytrailList == null) {
            return;
        }

        if ((waypointList != null && waypointList.size() < 1)
                && (routeList != null && routeList.size() < 1)
                && (waytrailList != null && waytrailList.size() < 1)) {
            return;
        }

        //创建输出目录
        File file = new File(EXDIR_GPX);
        if (!file.exists()) {
            file.mkdirs();
        }

        if (!file.exists()) {
            return;
        }

        SimpleDateFormat formatter = new SimpleDateFormat(
                "yyyy-MM-dd_HH.mm.ss");
        formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
        Date curDate = new Date(System.currentTimeMillis());
        String sufix = formatter.format(curDate);

        if (fileName == null || fileName.length() < 1) {
            fileName = EXDIR_GPX + sufix + ".gpx";
        } else {
            fileName = EXDIR_GPX + fileName + ".gpx";
        }

        OutputStreamWriter fos = null;
        try {
            fos = new OutputStreamWriter(new FileOutputStream(fileName), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        SimpleDateFormat formatterE = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        formatterE.setTimeZone(TimeZone.getTimeZone("GMT"));
        String strTime = "";
        try {
//            double minlat = 90;
//            double minlon = 180;
//            double maxlat = -90;
//            double maxlon = -180;
//            if (waypointList != null) {
//                for (WayPoint wp : waypointList) {
//                    if (minlat < wp.getLatitude()) {
//                        minlat = wp.getLatitude();
//                    }
//                    if (minlon < wp.getLongitude()) {
//                        minlon = wp.getLongitude();
//                    }
//                    if (maxlat > wp.getLatitude()) {
//                        maxlat = wp.getLatitude();
//                    }
//                    if (maxlon > wp.getLongitude()) {
//                        maxlon = wp.getLongitude();
//                    }
//                }
//            }
            //2006-01-01T20:04:41Z
            strTime = formatterE.format(new Date());

            String strC = String.format("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n" +
                    "<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\" version=\"1.1\" creator=\"BJHC\">\n" +
                    "\t<metadata>\n" +
                    "\t\t<link href=\"http://www.bhcnav.com/\">\n" +
                    "\t\t\t<text>BJHC</text>\n" +
                    "\t\t</link>\n" +
                    "\t\t<time>%s</time>\n" +
//                    "\t\t<bounds minlat=\"%f\" minlon=\"%f\" maxlat=\"%f\" maxlon=\"%f\"/>\n" +
                    "\t</metadata>\n\n", strTime/*, minlat, minlon, maxlat, maxlon*/);

            fos.write(strC.toCharArray());

            if (waypointList != null) {
                for (WayPoint wp : waypointList) {
                    strTime = formatterE.format(new Date(wp.getDatetime()));
                    strC = String.format("\t<wpt lat=\"%f\" lon=\"%f\">\n" +
                            "\t\t<ele>%f</ele>\n" +
                            "\t\t<time>%s</time>\n" +
                            "\t\t<name>%s</name>\n" +
                            "\t\t<cmt>%s</cmt>\n" +
                            "\t\t<desc>%s</desc>\n" +
                            "\t\t<link href=\"%s\"></link>\n" +
                            "\t\t<extensions>\n" +
                            "\t\t\t<gpxex:WaypointExtension xmlns:gpxex=\"http://www.bhcnav.com/xmlschemas/GpxExtensions\">\n" +
                            "\t\t\t\t<gpxex:mode value=\"1\"/>\n" +
                            "\t\t\t\t<gpxex:icon index=\"%d\"/>\n" +
                            "\t\t\t\t<gpxex:encrypt value=\"0\"/>\n" +
                            "\t\t\t</gpxex:WaypointExtension>\n" +
                            "\t\t</extensions>\n" +
                            "\t</wpt>\n", wp.getLatitude(), wp.getLongitude(), wp.getAltitude(), strTime, wp.getName(), wp.getNote(), wp.getNote(), wp.getPicurl(), wp.getIcon_num());
                    fos.write(strC.toCharArray());

//                    <gpxex:mode value="1"/>  原wince版本
                }
            }
            if (routeList != null && routeList.size() > 0) {
                for (Route rt : routeList) {

//                    minlat = 90;
//                    minlon = 180;
//                    maxlat = -90;
//                    maxlon = -180;
//                    for (WayPoint rwp : rt.waypointList) {
//                        if (minlat < rwp.getLatitude()) {
//                            minlat = rwp.getLatitude();
//                        }
//                        if (minlon < rwp.getLongitude()) {
//                            minlon = rwp.getLongitude();
//                        }
//                        if (maxlat > rwp.getLatitude()) {
//                            maxlat = rwp.getLatitude();
//                        }
//                        if (maxlon > rwp.getLongitude()) {
//                            maxlon = rwp.getLongitude();
//                        }
//                    }

                    strC = String.format("    <rte>\t\t<name>%s</name>\n" +
                            "\t\t<extensions>\n" +
                            "\t\t\t<gpxex:RouteExtension xmlns:gpxex=\"http://www.bhcnav.com/xmlschemas/GpxExtensions\">\n" +
//                            "\t\t\t\t<gpxex:bounds minlat=\"%f\" minlon=\"%f\" maxlat=\"%f\" maxlon=\"%f\"/>\n" +
                            "\t\t\t</gpxex:RouteExtension>\n" +
                            "\t\t</extensions>\n", rt.getName()/*, minlat, minlon, maxlat, maxlon*/);
                    fos.write(strC.toCharArray());

                    if (rt.waypointList != null) {
                        for (WayPoint rwp : rt.waypointList) {
                            strTime = formatterE.format(new Date(rwp.getDatetime()));
                            strC = String.format("\t\t<rtept lat=\"%f\" lon=\"%f\">\n" +
                                    "\t\t\t<ele>%f</ele>\n" +
                                    "\t\t\t<time>%s</time>\n" +
                                    "\t\t\t<name>%s</name>\n" +
                                    "\t\t\t<extensions>\n" +
                                    "\t\t\t\t<gpxex:RoutePointExtension xmlns:gpxex=\"http://www.bhcnav.com/xmlschemas/GpxExtensions\">\n" +
                                    "\t\t\t\t\t<gpxex:mode value=\"1\"/>\n" +
                                    "\t\t\t\t\t<gpxex:icon index=\"0\"/>\n" +
                                    "\t\t\t\t\t<gpxex:encrypt value=\"0\"/>\n" +
                                    "\t\t\t\t</gpxex:RoutePointExtension>\n" +
                                    "\t\t\t</extensions>\n" +
                                    "\t\t</rtept>\n", rwp.getLatitude(), rwp.getLongitude(), rwp.getAltitude(), strTime, rwp.getName());
                            fos.write(strC.toCharArray());
                        }
                    }
                    strC = "    </rte>\n";
                    fos.write(strC.toCharArray());
                }
            }
            if (waytrailList != null && waytrailList.size() > 0) {

                for (WayTrail wt : waytrailList) {
//                    strC = String.format("    <trk>\n" +
//                            "        <name>%s</name>\n" +
//                            "        <trkseg>\n", wt.getName());
//                    fos.write(strC.toCharArray());
//                    minlat = 90;
//                    minlon = 180;
//                    maxlat = -90;
//                    maxlon = -180;
//                    if (wt.trackPointList != null) {
//                        for (TrackPoint tp : wt.trackPointList) {
//                            if (minlat < tp.getLatitude()) {
//                                minlat = tp.getLatitude();
//                            }
//                            if (minlon < tp.getLongitude()) {
//                                minlon = tp.getLongitude();
//                            }
//                            if (maxlat > tp.getLatitude()) {
//                                maxlat = tp.getLatitude();
//                            }
//                            if (maxlon > tp.getLongitude()) {
//                                maxlon = tp.getLongitude();
//                            }
//                        }
//                    }

//                    "黑色", "红色", "蓝色", "绿色", "黄色"
                    String displayColor = "Black";
                    switch (wt.getColorstyle()) {
                        default:
                        case 0:
                            break;
                        case 1:
                            displayColor = "Red";
                            break;
                        case 2:
                            displayColor = "Blue";
                            break;
                        case 3:
                            displayColor = "Green";
                            break;
                        case 4:
                            displayColor = "Yellow";
                            break;

                    }
                    strC = String.format("\t<trk>\n" +
                            "\t\t<name>%s</name>\n" +
                            "\t\t<extensions>\n" +
                            "\t\t\t<gpxx:TrackExtension xmlns:gpxx=\"http://www.garmin.com/xmlschemas/GpxExtensions/v3\">\n" +
                            "\t\t\t\t<gpxx:DisplayColor>%s</gpxx:DisplayColor>\n" +
                            "\t\t\t</gpxx:TrackExtension>\n" +
                            "\t\t\t<gpxex:TrackExtension xmlns:gpxex=\"http://www.bhcnav.com/xmlschemas/GpxExtensions\">\n" +
                            "\t\t\t\t<gpxex:display value=\"1\"/>\n" +
//                            "\t\t\t\t<gpxex:bounds minlat=\"%f\" minlon=\"%f\" maxlat=\"%f\" maxlon=\"%f\"/>\n" +
                            "\t\t\t</gpxex:TrackExtension>\n" +
                            "\t\t</extensions>\n\t\t<trkseg>\n", wt.getName(), displayColor/*, minlat, minlon, maxlat, maxlon*/);
                    fos.write(strC.toCharArray());

                    if (wt.trackPointList != null) {
                        for (TrackPoint tp : wt.trackPointList) {
                            strTime = formatterE.format(new Date(tp.getDatetime()));
                            strC = String.format("            <trkpt lat=\"%f\" lon=\"%f\">\n" +
                                    "                <ele>%f</ele>\n" +
                                    "                <time>%s</time>\n" +
                                    "            </trkpt>\n", tp.getLatitude(), tp.getLongitude(), tp.getAltitude(), strTime);
                            fos.write(strC.toCharArray());
                        }
                    }
                    strC = "        </trkseg>\n";
                    fos.write(strC.toCharArray());
                    strC = "    </trk>\n";
                    fos.write(strC.toCharArray());
                }
            }

            strC = "</gpx>\n";
            fos.write(strC.toCharArray());
            fos.close();
        } catch (Exception e) {

        }
    }

    public void export2KML(String fileName, ArrayList<WayPoint> waypointList, ArrayList<Route> routeList, ArrayList<WayTrail> waytrailList) {
        if (waypointList == null && routeList == null && waytrailList == null) {
            return;
        }

        if ((waypointList != null && waypointList.size() < 1)
                && (routeList != null && routeList.size() < 1)
                && (waytrailList != null && waytrailList.size() < 1)) {
            return;
        }

        //创建输出目录
        File file = new File(EXDIR_KML);
        if (!file.exists()) {
            file.mkdirs();
        }

        if (fileName == null || fileName.length() < 1) {
            SimpleDateFormat formatter = new SimpleDateFormat(
                    "yyyy-MM-dd_HH.mm.ss");
            formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
            Date curDate = new Date(System.currentTimeMillis());
            String sufix = formatter.format(curDate);
            fileName = EXDIR_KML + sufix + ".KML";
        } else {
            fileName = EXDIR_KML + fileName + ".KML";
        }

        OutputStreamWriter fos = null;
        try {
            fos = new OutputStreamWriter(new FileOutputStream(fileName), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        SimpleDateFormat formatterE = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        formatterE.setTimeZone(TimeZone.getTimeZone("GMT"));
        String strTime = "";
        try {
            String strC = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" +
                    "<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\" xmlns:kml=\"http://www.opengis.net/kml/2.2\" xmlns:atom=\"http://www.w3.org/2005/Atom\">\n" +
                    "    <Document>\n" +
                    "        <name>Nava GPS Office</name>\n";
            fos.write(strC.toCharArray());

            if (waypointList != null && waypointList.size() > 0) {
                strC = "        <Folder>\n" +
                        "            <name>Waypoints</name>\n";
                fos.write(strC.toCharArray());
                for (WayPoint wp : waypointList) {
                    strTime = formatterE.format(new Date(wp.getDatetime()));
                    strC = String.format("            <Placemark>\n" +
                                    "                <name>%s</name>\n" +
                                    "                <description>%s</description>\n" +
                                    "                <Point>\n" +
                                    "                    <coordinates>%f,%f,%f</coordinates>\n" +
                                    "                </Point>\n" +
                                    "                <time>%s</time>\n" +
                                    "            </Placemark>\n", wp.getName(), wp.getNote(),
                            wp.getLongitude(), wp.getLatitude(), wp.getAltitude(), strTime);
                    fos.write(strC.toCharArray());
                }
                strC = "        </Folder>\n";
                fos.write(strC.toCharArray());
            }
            if (routeList != null && routeList.size() > 0) {
                strC = "        <Folder>\n" +
                        "                <name>Routes</name>\n";
                fos.write(strC.toCharArray());
                for (Route rt : routeList) {
                    String strLinePt = "";
                    if (rt.waypointList != null) {
                        for (WayPoint rwp : rt.waypointList) {
                            strLinePt += String.format("%f,%f,%f ", rwp.getLongitude(), rwp.getLatitude(), rwp.getAltitude());
                        }
                    }

                    strC = String.format("                <Folder>\n" +
                            "                    <name>%s</name>\n" +
                            "                    <Placemark>\n" +
                            "                        <name>%s</name>\n" +
                            "                        <LineString>\n" +
                            "                            <tessellate>1</tessellate>\n" +
                            "                            <coordinates>%s</coordinates>\n" +
                            "                        </LineString>\n" +
                            "                    </Placemark>\n" +
                            "                </Folder>\n", rt.getName(), rt.getName(), strLinePt);
                    fos.write(strC.toCharArray());
                }
                strC = "        </Folder>\n";
                fos.write(strC.toCharArray());
            }
            if (waytrailList != null && waytrailList.size() > 0) {
                strC = "        <Folder>\n" +
                        "                <name>Tracks</name>\n";
                fos.write(strC.toCharArray());
                for (WayTrail wt : waytrailList) {
                    String strLinePt = "";
                    if (wt.trackPointList != null) {
                        for (TrackPoint tp : wt.trackPointList) {
                            strLinePt += String.format("%f,%f,%f ", tp.getLongitude(), tp.getLatitude(), tp.getAltitude());
                        }
                    }

                    strC = String.format("                <Folder>\n" +
                            "                    <name>%s</name>\n" +
                            "                    <Placemark>\n" +
                            "                        <name>%s</name>\n" +
                            "                        <LineString>\n" +
                            "                            <tessellate>1</tessellate>\n" +
                            "                            <coordinates>%s</coordinates>\n" +
                            "                        </LineString>\n" +
                            "                    </Placemark>\n" +
                            "                </Folder>\n", wt.getName(), wt.getName(), strLinePt);
                    fos.write(strC.toCharArray());
                }
                strC = "        </Folder>\n";
                fos.write(strC.toCharArray());
            }

            strC = "    </Document>\n\n" + "</kml>\n";
            fos.write(strC.toCharArray());
            fos.close();
        } catch (Exception e) {

        }
    }

    private ArrayList<WayPoint> mWaypointList = new ArrayList<WayPoint>();
    private ArrayList<Route> mRouteList = new ArrayList<Route>();
    private ArrayList<WayTrail> mWaytrailList = new ArrayList<WayTrail>();

    //http://blog.csdn.net/qq_30379689/article/details/53170075
    public boolean importGPX(String filePath) {
        mWaypointList.clear();
        mRouteList.clear();
        mWaytrailList.clear();

        WayPoint wp = null;
        Route rt = null;
        WayPoint rwp = null;//route 里面的wp
        WayTrail wt = null;
        TrackPoint tp = null;

        SimpleDateFormat formatterE = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        formatterE.setTimeZone(TimeZone.getTimeZone("GMT"));

        boolean isGpx = false;

        long A = System.currentTimeMillis();

        try {
//            InputStream is = mContext.getResources().getAssets().open("gpx.smp");
            FileInputStream is = new FileInputStream(filePath);

            //创建xmlPull解析器
            XmlPullParser parser = Xml.newPullParser();
            ///初始化xmlPull解析器
            parser.setInput(is, "utf-8");
            //读取文件的类型
            int type = parser.getEventType();
            //无限判断文件类型进行读取
            while (type != XmlPullParser.END_DOCUMENT) {
                switch (type) {
                    //开始标签
                    case XmlPullParser.START_TAG:
                        String xx = parser.getName();
                        if ("wpt".equals(parser.getName())) {
                            if (!isGpx) {
                                return false;
                            }
                            String strLat = parser.getAttributeValue(null, "lat");
                            String strLon = parser.getAttributeValue(null, "lon");
                            double lon = Double.valueOf(StringUtil.getTrimedString(strLon));
                            double lat = Double.valueOf(StringUtil.getTrimedString(strLat));
                            wp = new WayPoint("", new LonLat(lon, lat));
                        } else if ("ele".equals(parser.getName())) {
                            String strAlt = parser.nextText();
                            double alt = Double.valueOf(strAlt);
                            if (wp != null) {
                                wp.setAltitude(alt);
                            } else if (rt != null && rwp != null) {
                                rwp.setAltitude(alt);
                            } else if (wt != null && tp != null) {
                                tp.setAltitude(alt);
                            }
                        } else if ("name".equals(parser.getName())) {
                            String name = parser.nextText();
                            if (wp != null) {
                                wp.setName(name);
                            } else if (rt != null) {
                                if (rwp != null) {
                                    rwp.setName(name);
                                } else {
                                    rt.setName(name);
                                }
                            } else if (wt != null) {
                                wt.setName(name);
                            }
                        } else if ("cmt".equals(parser.getName())) {
                            String cmt = parser.nextText();
                            if (wp != null && cmt.length() > 0) {
                                wp.setNote(cmt);
                            }
                        } else if ("desc".equals(parser.getName())) {
                            String desc = parser.nextText();
                            if (wp != null && desc.length() > 0) {
                                wp.setNote(desc);
                            }
                        } else if ("link".equals(parser.getName())) {
                            String link = parser.getAttributeValue(null, "href");
                            if (wp != null && link.length() > 0) {
                                wp.setPicurl(link);
                            }
                        } else if ("time".equals(parser.getName())) {
                            String time = parser.nextText();
                            //yyyy-MM-ddTHH:mm:ssZ
                            //2018-02-24T18:36:36Z
                            time = time.replace("T", " ");
                            time = time.replace("Z", "");
                            long datetime = Utils.getDateTime(time, formatterE);
                            if (datetime > 0) {
                                if (wp != null) {
                                    wp.setDatetime(datetime);
                                } else if (rt != null && rwp != null) {
                                    rwp.setDatetime(datetime);
                                } else if (wt != null && tp != null) {
                                    tp.setDatetime(datetime);
                                }
                            }
                        } else if ("rte".equals(parser.getName())) {
                            if (!isGpx) {
                                return false;
                            }
                            rt = new Route();
                            rt.waypointList = new ArrayList<WayPoint>();
                        } else if ("rtept".equals(parser.getName())) {
                            String strLat = parser.getAttributeValue(null, "lat");
                            String strLon = parser.getAttributeValue(null, "lon");
                            double lon = Double.valueOf(StringUtil.getTrimedString(strLon));
                            double lat = Double.valueOf(StringUtil.getTrimedString(strLat));
                            if (rt != null) {
                                rwp = new WayPoint("", new LonLat(lon, lat));
                            }
                        } else if ("trkpt".equals(parser.getName())) {
                            String strLat = parser.getAttributeValue(null, "lat");
                            String strLon = parser.getAttributeValue(null, "lon");
                            double lon = Double.valueOf(StringUtil.getTrimedString(strLon));
                            double lat = Double.valueOf(StringUtil.getTrimedString(strLat));
                            if (wt != null) {
                                tp = new TrackPoint();
                                tp.setLL(new LonLat(lon, lat));
                            }
                        } else if ("trk".equals(parser.getName())) {
                            if (!isGpx) {
                                return false;
                            }
                            wt = new WayTrail();
                            wt.randColor();
                            wt.trackPointList = new ArrayList<TrackPoint>();
                        } else if ("gpx".equals(parser.getName())) {
                            isGpx = true;
                        }
                        break;
                    //结束标签
                    case XmlPullParser.END_TAG:
                        if ("wpt".equals(parser.getName())) {
                            mWaypointList.add(wp);
                            wp = null;
                        } else if ("rte".equals(parser.getName())) {
                            mRouteList.add(rt);
                            rt = null;
                            rwp = null;
                        } else if ("rtept".equals(parser.getName())) {
                            if (rt != null && rwp != null && rt.waypointList != null) {
                                rt.waypointList.add(rwp);
                                rwp = null;
                            }
                        } else if ("trk".equals(parser.getName())) {
                            mWaytrailList.add(wt);
                            wt = null;
                            tp = null;
                        } else if ("trkseg".equals(parser.getName())) {

                        } else if ("trkpt".equals(parser.getName())) {
                            if (wt != null && tp != null && wt.trackPointList != null) {
                                wt.trackPointList.add(tp);
                                tp = null;
                            }
                        }
                        break;
                }
                //继续往下读取标签类型
                type = parser.next();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return add2DB();
    }

    public boolean importKML(String filePath) {
        try {
            FileInputStream is = new FileInputStream(filePath);
            return parserKML(is);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    //KXmlParser
//    https://blog.csdn.net/shanhuhau/article/details/38326021
    boolean parserKML(InputStream is) {
        if (is == null) {
            return false;
        }
        mWaypointList.clear();
        mRouteList.clear();
        mWaytrailList.clear();

        SimpleDateFormat formatterE = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        formatterE.setTimeZone(TimeZone.getTimeZone("GMT"));

        boolean isKML = false;
        KMLFolder folder = null;
        KMLPlacemark placemark = null;

        try {
            //创建xmlPull解析器
            XmlPullParser parser = Xml.newPullParser();
            ///初始化xmlPull解析器
            parser.setInput(is, "utf-8");
            //读取文件的类型
            int type = parser.getEventType();
            //无限判断文件类型进行读取
            while (type != XmlPullParser.END_DOCUMENT) {
                switch (type) {
                    //开始标签
                    case XmlPullParser.START_TAG:
                        if ("Folder".equals(parser.getName())) {
                            if (!isKML) {
                                return false;
                            }
                            if (folder == null) {
                                folder = new KMLFolder();
                            } else {
                                folder.Folder++;
                            }
                        } else if ("Placemark".equals(parser.getName())) {
                            placemark = new KMLPlacemark();
                        } else if ("name".equals(parser.getName())) {
                            String name = parser.nextText();
                            if (placemark != null) {
                                placemark.name = name;
                            } else if (folder != null) {
                                folder.addName(name);
                            }
                        } else if ("styleUrl".equals(parser.getName())) {
                            String name = parser.nextText();
                            if (placemark != null) {
                                placemark.styleUrl = name;
                            }
                        } else if ("LineString".equals(parser.getName())) {
                            if (placemark != null) {
                                placemark.haveLineString = true;
                            }
                        } else if ("altitudeMode".equals(parser.getName())) {
                            String name = parser.nextText();
                            if (placemark != null) {
                                placemark.altitudeMode = name;
                            }
                        } else if ("time".equals(parser.getName()) || "begin".equals(parser.getName())) {
                            String time = parser.nextText();
                            if (placemark != null) {
                                //yyyy-MM-ddTHH:mm:ssZ
                                time = time.replace(".", "-");
                                time = time.replace(".", "-");
                                long datetime = Utils.getDateTime(time, formatterE);
                                placemark.datetime = datetime;
                            }
                        } else if ("description".equals(parser.getName())) {
                            String note = parser.nextText();
                            if (placemark != null) {
                                placemark.description = note;
                            }
                        } else if ("coordinates".equals(parser.getName())) {
                            String coordinates = parser.nextText();
                            String c[] = coordinates.split(" ");
                            if (c != null && placemark != null) {
                                int size = c.length;
                                for (int i = 0; i < size; i++) {
                                    if (c[i].length() < 1) {
                                        continue;
                                    }
                                    String d[] = c[i].split(",");
                                    if (d != null && d.length == 3) {
                                        Coordinate coord = new Coordinate();
                                        coord.longitude = Double.valueOf(StringUtil.getTrimedString(d[0]));
                                        coord.latitude = Double.valueOf(StringUtil.getTrimedString(d[1]));
                                        coord.altitude = Double.valueOf(StringUtil.getTrimedString(d[2]));
                                        placemark.coordList.add(coord);
                                    }
                                }
                            }
                        } else if ("kml".equals(parser.getName())) {
                            isKML = true;
                        }
                        break;
                    //结束标签
                    case XmlPullParser.END_TAG:
                        if ("Folder".equals(parser.getName())) {
                            if (folder != null) {
                                folder.Folder--;
                                if (folder.Folder < 0) {
                                    //加入到航点，航线，航迹
                                    setAll2List(folder);
                                    folder = null;
                                }
                            }
                        } else if ("Placemark".equals(parser.getName())) {
                            if (folder != null && placemark != null) {
                                folder.placemarkList.add(placemark);
                                placemark = null;
                            }
                        }
                        break;
                }
                //继续往下读取标签类型
                type = parser.next();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return add2DB();
    }


    public boolean importKMZ(String filePath) {
        boolean isOK = false;
        try {
            InputStream isKxml = null;
            FileInputStream is = new FileInputStream(filePath);
            ZipInputStream zipIs = new ZipInputStream(is);
            ZipEntry zipEntry = null;
            while ((zipEntry = zipIs.getNextEntry()) != null) {
                String zipEntryName = zipEntry.getName();
                if (zipEntryName.endsWith("kml")) {
                    ByteArrayOutputStream os = new ByteArrayOutputStream();
                    byte[] b = new byte[512];
                    int readedByteSize = 0;
                    while ((readedByteSize = zipIs.read(b)) > 0) {
                        os.write(b, 0, readedByteSize);
                    }
                    os.flush();
                    os.close();
                    isKxml = new ByteArrayInputStream(os.toByteArray());
                    if (parserKML(isKxml)) {
                        isOK = true;
                    }
                }
            }
            zipIs.close();
            return isOK;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    private void setAll2List(KMLFolder folder) {
        if (folder == null) {
            return;
        }

        if (folder.type == 0) {
            if (folder.folder0Name.compareToIgnoreCase("Routes") == 0) {
                folder.type = 1;//1个Folder里可能有多条航线
            } else if (folder.folder0Name.compareToIgnoreCase("Tracks") == 0) {
                folder.type = 2;
            } else if (folder.folder0Name.compareToIgnoreCase("Line Features") == 0) {
                //Global Mapper格式；航线航迹无法区分，都在一个Folder里
                doGlobalMapper(folder);
                return;
            }
        }

        ArrayList<WayPoint> waypointList1 = new ArrayList<WayPoint>();
        ArrayList<WayPoint> waypointList2 = new ArrayList<WayPoint>();//LineString---没有时间,自定义时间

        boolean isOldKML = false;
        long datetime = System.currentTimeMillis();
        int size = folder.placemarkList.size();
        for (int i = 0; i < size; i++) {
            KMLPlacemark placemark = folder.placemarkList.get(i);
            if (placemark.coordList.size() < 1) {
                continue;
            }
            int sizeC = placemark.coordList.size();
            if (sizeC > 1) {
                for (int j = 0; j < sizeC; j++) {
                    WayPoint wp = new WayPoint();
                    Coordinate coord = placemark.coordList.get(j);
                    wp.setLL(coord.longitude, coord.latitude);
                    wp.setAltitude(coord.altitude);
                    wp.setDatetime(datetime + i * 1000);
                    waypointList2.add(wp);
                }
                isOldKML = true;
                //如果是航线（本app保存的原格式KML; 一个KMLPlacemark一条航线
                if (folder.type == 1) {
                    Route rt = new Route();
                    rt.setName(placemark.name);
                    int size2 = waypointList2.size();
                    for (int k = 0; k < size2; k++) {
                        rt.waypointList.add(waypointList2.get(k));
                    }
                    mRouteList.add(rt);
                    waypointList2.clear();
                }
            } else {
                WayPoint wp = new WayPoint();
                Coordinate coord = placemark.coordList.get(0);
                wp.setLL(coord.longitude, coord.latitude);
                wp.setAltitude(coord.altitude);
                wp.setName(placemark.name);
                wp.setDatetime(placemark.datetime);
                wp.setNote(placemark.description);
                waypointList1.add(wp);
            }
        }

        if (isOldKML) {
            return;
        }

        int size1 = waypointList1.size();
        int size2 = waypointList2.size();

        if (folder.type == 0) {
            for (int i = 0; i < size1; i++) {
                mWaypointList.add(waypointList1.get(i));
            }
        } else if (folder.type == 1) {
            Route rt = new Route();
            rt.setName(folder.folder1Name);
            if (size1 > 0) {
                //如果没有N航点；则使用LineString的点
                for (int i = 0; i < size1; i++) {
                    rt.waypointList.add(waypointList1.get(i));
                }
            } else {
                for (int i = 0; i < size2; i++) {
                    rt.waypointList.add(waypointList2.get(i));
                }
            }
            mRouteList.add(rt);
        } else if (folder.type == 2) {
            WayTrail wt = new WayTrail();
            wt.trackPointList = new ArrayList<TrackPoint>();
            wt.setName(folder.folder1Name);
            if (size1 > 0) {
                for (int i = 0; i < size1; i++) {
                    WayPoint wp = waypointList1.get(i);
                    TrackPoint tp = new TrackPoint();
                    tp.setLL(wp.getLL());
                    tp.setAltitude(wp.getAltitude());
                    tp.setDatetime(wp.getDatetime());
                    wt.trackPointList.add(tp);
                }
            } else {
                for (int i = 0; i < size2; i++) {
                    WayPoint wp = waypointList2.get(i);
                    TrackPoint tp = new TrackPoint();
                    tp.setLL(wp.getLL());
                    tp.setAltitude(wp.getAltitude());
                    tp.setDatetime(wp.getDatetime());
                    wt.trackPointList.add(tp);
                }
            }
            mWaytrailList.add(wt);
        }

    }

    private void doGlobalMapper(KMLFolder folder) {
        if (folder == null) {
            return;
        }

        //Global Mapper这个格式，航线和航迹无法区分；都作为航迹
        int size = folder.placemarkList.size();
        for (int i = 0; i < size; i++) {
            KMLPlacemark placemark = folder.placemarkList.get(i);
            if (placemark.coordList.size() < 1) {
                continue;
            }
            long datetime = System.currentTimeMillis();
            int sizeC = placemark.coordList.size();
            WayTrail wt = new WayTrail();
            wt.trackPointList = new ArrayList<TrackPoint>();
            wt.setName(placemark.name);
            for (int j = 0; j < sizeC; j++) {
                Coordinate coord = placemark.coordList.get(j);
                TrackPoint tp = new TrackPoint();
                tp.setLL(coord.longitude, coord.latitude);
                tp.setAltitude(coord.altitude);
                tp.setDatetime(datetime + i * 1000);
                wt.trackPointList.add(tp);
            }
            mWaytrailList.add(wt);
        }
    }

    private boolean add2DB() {

        boolean isOK = false;
        long X1, X2, X3;
        long X11, X22, X33;
        long A, B, C;

        WayPointDao wayPointDao = AppContext.getInstances().getDaoSession().getWayPointDao();
        if (wayPointDao == null) {
            return isOK;
        }
        if (mWaypointList.size() > 0) {
            wayPointDao.insertOrReplaceInTx(mWaypointList);
            DBDataCenter.getInstance().doQueryWayPoint();

            isOK = true;
        }

        if (mRouteList.size() > 0) {
            A = System.currentTimeMillis();

            RouteDao routeDao = AppContext.getInstances().getDaoSession().getRouteDao();
            for (Route rt : mRouteList) {
                long id = routeDao.insert(rt);
                rt.setId(id);
                String waypoint = "";
                if (rt.waypointList != null) {
                    int i = 0;
                    for (WayPoint rwp : rt.waypointList) {
                        rwp.setRouteid(id);
                        if (rwp.getName().length() < 1) {
                            rwp.setName(id + "-" + i); //不需要改名
                        }
                        long wid = wayPointDao.insert(rwp);
                        if (i == 0) {
                            waypoint = wid + "";
                        } else {
                            waypoint += "-" + wid;
                        }
                        i++;
                    }
                }
                rt.setWaypoint(waypoint);
            }
            routeDao.insertOrReplaceInTx(mRouteList);
            B = System.currentTimeMillis();
            X2 = B - A;
            DBDataCenter.getInstance().doQueryRoute();

            C = System.currentTimeMillis();
            X22 = C - B;

            C = System.currentTimeMillis();
            isOK = true;
        }

        if (mWaytrailList.size() > 0) {
            A = System.currentTimeMillis();

            WayTrailDao wayTrailDao = AppContext.getInstances().getDaoSession().getWayTrailDao();
            TrackPointDao trackPointDao = AppContext.getInstances().getDaoSession().getTrackPointDao();

            for (WayTrail wt : mWaytrailList) {
                long id = wayTrailDao.insert(wt);
                wt.setId(id);
                wt.setIsshow(false);
                int k = 0;
                if (wt.trackPointList != null) {
                    for (TrackPoint tp : wt.trackPointList) {
                        tp.setWaytrail_id(id);
                        if (k == 0) {
                            wt.setStarttime(tp.getDatetime());
                        }
                        k++;
                    }
                    trackPointDao.insertOrReplaceInTx(wt.trackPointList);
                }
                wt = DBDataCenter.getInstance().reUpdateWayTrail(wt);
            }
            wayTrailDao.insertOrReplaceInTx(mWaytrailList);

            B = System.currentTimeMillis();
            X3 = B - A;

            DBDataCenter.getInstance().doQueryWayTrail();

            C = System.currentTimeMillis();
            X33 = C - B;

            C = System.currentTimeMillis();
            isOK = true;
        }

        return isOK;
    }

    public boolean export2GPX_today() {

        boolean isok = false;
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");

        //航点
        ArrayList<WayPoint> waypointList = DBDataCenter.getInstance().getWaypointList();
        int count = waypointList.size();
        for (int i = 0; i < count; ++i) {
            WayPoint wp = waypointList.get(i);
            if (wp.strDate.length() < 1) {
                Date curDate = new Date(wp.getDatetime());
                wp.strDate = formatter.format(curDate);
            }
        }
        //航点按天分组
        Map<String, ArrayList<WayPoint>> groupWp = new HashMap<>();
        for (WayPoint wp : waypointList) {
            ArrayList<WayPoint> tempList = groupWp.get(wp.strDate);
            if (tempList == null) {
                tempList = new ArrayList<>();
                tempList.add(wp);
                groupWp.put(wp.strDate, tempList);
            } else {
                tempList.add(wp);
            }
        }

        for (String strDate : groupWp.keySet()) {
            ArrayList<WayPoint> tempList = groupWp.get(strDate);
            export2GPX("航点" + strDate, tempList, null, null);
            isok = true;
        }

        //航线
        ArrayList<Route> naviLineList = DBDataCenter.getInstance().getRouteList();
        count = naviLineList.size();
        for (int i = 0; i < count; ++i) {
            Route rt = naviLineList.get(i);
            if (rt.strDate.length() < 1) {
                Date curDate = new Date(rt.getDatetime());
                rt.strDate = formatter.format(curDate);
            }
        }
        Map<String, ArrayList<Route>> groupRt = new HashMap<>();
        for (Route rt : naviLineList) {
            ArrayList<Route> tempList = groupRt.get(rt.strDate);
            if (tempList == null) {
                tempList = new ArrayList<>();
                tempList.add(rt);
                groupRt.put(rt.strDate, tempList);
            } else {
                tempList.add(rt);
            }
        }

        for (String strDate : groupRt.keySet()) {
            ArrayList<Route> tempList = groupRt.get(strDate);
            export2GPX("航线" + strDate, null, tempList, null);
            isok = true;
        }
        //航迹
//        DBDataCenter.getInstance().saveAsThisWayTrail();
        long wayTrailThis = 0;
        if (DBDataCenter.getInstance().wayTrailThis != null) {
            DBDataCenter.getInstance().closeThisWayTrail();
            DBDataCenter.getInstance().startThisWayTrail();
            wayTrailThis = DBDataCenter.getInstance().wayTrailThis.getId();
        }
        ArrayList<WayTrail> waytrailList = DBDataCenter.getInstance().getWaytrailList();
        count = waytrailList.size();
        for (int i = 0; i < count; ++i) {
            WayTrail wt = waytrailList.get(i);
            if (wt.strDate.length() < 1) {
                Date curDate = new Date(wt.getEndtime());
                wt.strDate = formatter.format(curDate);
            }

            if (wt.trackPointList == null || wt.trackPointList.size() < 1) {
                DBDataCenter.getInstance().reUpdateWayTrail(wt);
            }

        }
        Map<String, ArrayList<WayTrail>> groupWt = new HashMap<>();
        for (WayTrail wt : waytrailList) {
            if (wayTrailThis == wt.getId()) {
                continue;//当前记录不重复记录
            }
            ArrayList<WayTrail> tempList = groupWt.get(wt.strDate);
            if (tempList == null) {
                tempList = new ArrayList<>();
                tempList.add(wt);
                groupWt.put(wt.strDate, tempList);
            } else {
                tempList.add(wt);
            }
        }

        for (String strDate : groupWt.keySet()) {
            ArrayList<WayTrail> tempList = groupWt.get(strDate);
            export2GPX("航迹" + strDate, null, null, tempList);
            isok = true;
        }

        return isok;
    }
}
